﻿#include "udpmsgprocess.h"

UdpMsgProcess::UdpMsgProcess(QObject *parent) : QObject(parent)
{
    this->filePath = new QString;
    logname = new QString;
    regularTime = new int;
    bakdata = new bool(false);

    // 加入新线程并启动
    this->moveToThread(&_thread);


    // 使用队列连接方式连接线程处理函数,此处连接类型必须使用BlockingQueuedConnection，使用QueuedConnection会导致readyRead信号只接收1次后就再也收不到了
    connect(&_socket, &QUdpSocket::readyRead, this, &UdpMsgProcess::slotReadyRead, Qt::ConnectionType::BlockingQueuedConnection);
    // connect(this, &UdpMsgProcess::destroyed, this, &UdpMsgProcess::onSocketDestroyed);

    // 绑定定时器信号
    connect(&_timer, &QTimer::timeout, this, &UdpMsgProcess::slotSaveLog, Qt::UniqueConnection);
}

UdpMsgProcess::~UdpMsgProcess()
{

}


// 端口绑定
bool UdpMsgProcess::bind(SYSTEM local, SYSTEM remote)
{
    // 绑定端口
    bool res = _socket.bind(QHostAddress(local.ip), local.port.toInt());

#ifndef PC
//    emit startReq();
    remote_ip = remote.ip;
    remote_port = remote.port.toInt();
    _socket.writeDatagram(intToByte(pCommon->PLT_REQUEST_MSG).mid(0,1), QHostAddress(remote_ip), remote_port);
#else
    Q_UNUSED(remote)
#endif
    return res;
}


// 线程处理函数
void UdpMsgProcess::slotReadyRead()
{
    while(_socket.hasPendingDatagrams())
    {

        // 读取UDP数据
        QByteArray* datagram = new QByteArray;
        datagram->resize(_socket.pendingDatagramSize());
        _socket.readDatagram(datagram->data(), datagram->size());

#ifndef PC
        // 过滤首字节为0x01的debug_info
        if(datagram->mid(0, 1).toHex().compare(intToByte(pCommon->PLT_MSG_TYPE).mid(0,1).toHex()) != 0)
        {
            return;
        }

        // 申请回包
        emit setFlag(true);
        _socket.writeDatagram(intToByte(pCommon->PLT_REQUEST_MSG).mid(0,1), QHostAddress(remote_ip), remote_port);
        qDebug()<<"Request:"<<intToByte(pCommon->PLT_REQUEST_MSG).mid(0,1);
#endif

        // 批量接收，定期保存时的处理，即当定时器启动时
        if(_timer.isActive())
        {
            if(*bakdata)
            {
                pReceivedDataBak->append(datagram);
            }
            else
            {
                pReceivedData->append(datagram);
            }
            continue;
        }

        // 实时处理时的处理
        emit receivedData(datagram);
    }

    return;
}


void UdpMsgProcess::stopReceive()
{
    if (!isStarted) return;

    // disconnect(&_socket, &QUdpSocket::destroyed, this, &UdpMsgProcess::slotReadyRead);

    if(!_socket.isValid()) return;
    _socket.close();


    if(_timer.isActive())
    {
        _timer.stop();

        if (_thread.isRunning()) _thread.quit();

        _thread.wait();

        QString date = QDateTime::currentDateTime().date().toString("yyyy-MM-dd");;
        QString time = QDateTime::currentDateTime().time().toString("hh.mm.ss");

        *logname += date + QString(" ") + time + QString(".dat");

        threadSaveLog = new SaveLogThread;

        if(*bakdata)
        {
            threadSaveLog->setSave(*logname, pReceivedDataBak);
            *bakdata = false;
        }
        else
        {
            threadSaveLog->setSave(*logname, pReceivedData);
            *bakdata = true;
        }
        threadSaveLog->run();

        logname->clear();
        *bakdata = false;
    }
    isStarted = false;
    return;

}

void UdpMsgProcess::slotSaveLog()
{
    QString date = QDateTime::currentDateTime().date().toString("yyyy-MM-dd");;
    QString time = QDateTime::currentDateTime().time().toString("hh.mm.ss");
    *logname += date + QString(" ") + time + QString(".dat");

    threadSaveLog = new SaveLogThread;

    if(*bakdata)
    {
        pReceivedData = new QVector<QByteArray*>;
        threadSaveLog->setSave(*logname, pReceivedDataBak);
        *bakdata = false;
    }
    else
    {
        pReceivedDataBak = new QVector<QByteArray*>;
        threadSaveLog->setSave(*logname, pReceivedData);
        *bakdata = true;
    }
    threadSaveLog->run();

    // 重新开始
    logname->clear();
    QString newDate = QDateTime::currentDateTime().date().toString("yyyy-MM-dd");;
    QString newTime = QDateTime::currentDateTime().time().toString("hh.mm.ss");
    *logname = *this->filePath + QString("\\") + newDate + QString(" ") + newTime + QString(" - ");

    return;
}

// void UdpMsgProcess::onSocketDestroyed()
// {
//     // 断开信号连接
//     disconnect(&_socket, &UdpMsgProcess::destroyed, this, &UdpMsgProcess::onSocketDestroyed);

//     // 在这里执行关闭操作
//     _socket.close();
// }



void UdpMsgProcess::setCurrentCycle(pCYCLE_ATTR pCycle)
{
    this->pCycle = pCycle;

    return;
}


void UdpMsgProcess::regularSave(QString filePath)
{
    *this->filePath = filePath;
    pReceivedData = new QVector<QByteArray*>(RECEIVE_CYCLES_CAPACITY);
    pReceivedData->clear();
    pReceivedDataBak = new QVector<QByteArray*>(RECEIVE_CYCLES_CAPACITY);
    pReceivedDataBak->clear();

    // 日志开始记录时间
    QString date = QDateTime::currentDateTime().date().toString("yyyy-MM-dd");;
    QString time = QDateTime::currentDateTime().time().toString("hh.mm.ss");

    _timer.start();

    logname->clear();
    *logname = *this->filePath + QString("\\") + date + QString(" ") + time + QString(" - ");

    QDir dir;
    if(!dir.exists(QDir::fromNativeSeparators(filePath)))
    {
        mkMutiDir(QDir::fromNativeSeparators(filePath));
    }

    return;
}


void UdpMsgProcess::setRegularSaveTime(int time)
{
    _timer.setInterval(time * 60 * 1000);

    return;
}


void UdpMsgProcess::setCommonParameters(pCOMMONS pCommon)
{
    this->pCommon = pCommon;

    return;
}

void UdpMsgProcess::startReceive()
{
    _thread.start();
    isStarted = true;
}





